package org.jing.core.lang.data.json;

import org.jing.core.lang.JingException;

import java.io.IOException;
import java.io.Reader;

/**
 * Description: 字符读取 <br>
 *
 * @author bks <br>
 * @since 2024-07-22 <br>
 */
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
public class CharReader {
    private static final int BUFFER_SIZE = 1024;

    private final Reader reader;

    private final char[] buffer;

    private int pos;

    private int size;

    public CharReader(Reader reader) {
        this.reader = reader;
        buffer = new char[BUFFER_SIZE];
    }

    /**
     * Description: 获取当前字符 <br>
     *
     * @return 当前字符 <br>
     */
    char peek() {
        if (pos - 1 >= size) {
            return (char) -1;
        }

        return buffer[Math.max(0, pos - 1)];
    }

    /**
     * Description: 获取当前字符, 游标向后移动一位 <br>
     *
     * @return 当前字符 <br>
     */
    char next() {
        try {
            if (!hasMore()) {
                return (char) -1;
            }
        }
        catch (JingException e) {
            throw e;
        }
        catch (Throwable t) {
            throw new JingException(t);
        }
        return buffer[pos++];
    }

    /**
     * Description: 游标向前移动一位 <br>
     */
    void back() {
        pos = Math.max(0, --pos);
    }

    /**
     * Description: 是否可以继续读取 <br>
     *
     * @return <br>
     */
    boolean hasMore() {
        try {
            if (pos < size) {
                return true;
            }
            fillBuffer();
            return pos < size;
        }
        catch (JingException e) {
            throw e;
        }
        catch (Throwable t) {
            throw new JingException(t);
        }
    }

    /**
     * Description: 从输入流中读取字符串到字节数组里 <br>
     *
     * @throws JingException 读取失败 <br>
     */
    private void fillBuffer() throws IOException {
        int n = reader.read(buffer);
        if (n == -1) {
            return;
        }
        pos = 0;
        size = n;
    }
}
